package com.rslai.commons.validator.jsonvalidator.builder;

import com.rslai.commons.validator.jsonvalidator.factories.ValidatorFactory;
import com.rslai.commons.validator.jsonvalidator.schema.Attr;
import com.rslai.commons.validator.jsonvalidator.schema.Schema;
import com.rslai.commons.validator.jsonvalidator.validators.DefaultValidator;
import com.rslai.commons.validator.jsonvalidator.validators.SchemaValidator;
import com.rslai.commons.validator.jsonvalidator.validators.Validator;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Validator构造器
 */
public class ValidatorBuilder {
    private List<Validator> validatorList;

    /**
     * 使用属性生成
     * @param attrList 属性list
     * @param currentKeyPath 当前key
     * @param valueSchema 值的Schema
     * @return 当前构造器
     */
    public ValidatorBuilder withAttrs(List<Attr> attrList, String currentKeyPath, Schema<?> valueSchema) {
        validatorList = buildValidator(attrList, currentKeyPath, valueSchema);
        if (validatorList.size() > 0) {
            for (int i = 0; i < validatorList.size() - 1; i++) {
                validatorList.get(i).setNextValidator(validatorList.get(i + 1));
            }
        }
        return this;
    }

    /**
     * 使用Schema生成
     * @param parentKey 父级key
     * @param schema schema
     * @return 当前构造器
     */
    public ValidatorBuilder withSchema(String parentKey, Schema<Object> schema) {
        SchemaValidator validator = new SchemaValidator(parentKey, schema);
        addLastValidator(validator);
        return this;
    }

    /**
     * 向Validator构造器最后添加一个validator
     * @param validator validator
     */
    private void addLastValidator(Validator validator) {
        int size = getValidatorList().size();
        if (size != 0) {
            getValidatorList().get(size - 1).setNextValidator(validator);
        } else {
            getValidatorList().add(validator);
        }
    }

    /**
     * 添加一个validator
     * @param validator validator
     * @return 当前构造器
     */
    public ValidatorBuilder withOtherValidator(Validator validator) {
        addLastValidator(validator);
        return this;
    }

    /**
     * build
     * @return 第一个validator
     */
    public Validator build() {
        if (getValidatorList().size() < 1) {
            return new DefaultValidator();
        }
        return validatorList.get(0);
    }

    /**
     * 返回validatorList
     * @return validatorList
     */
    public List<Validator> getValidatorList() {
        if (validatorList == null) {
            return Collections.emptyList();
        }
        return validatorList;
    }

    /**
     * 构造Validator
     * @param attrList 属性list
     * @param concurrentKeyPath 当前key
     * @param valueSchema 值的Schema
     * @return ValidatorList
     */
    private static List<Validator> buildValidator(List<Attr> attrList, String concurrentKeyPath, Schema<?> valueSchema) {
        List<Validator> result = new ArrayList<Validator>();
        for (Attr attr : attrList) {
            String attrName = attr.getAttrName();
            List<Object> arguments = attr.getArguments();
            Validator validator = ValidatorFactory.getValidator(attrName, arguments);
            validator.setCurrentKeyPath(concurrentKeyPath);
            validator.setValueSchema(valueSchema);
            result.add(validator);
        }
        return result;
    }

}
